package hyl.base.cache2;

import java.util.concurrent.ConcurrentLinkedQueue;

import com.alibaba.fastjson2.JSON;

import hyl.core.data.ExpValue;

/**
 * 可回收式队列 无cache 适用于 特殊场景
 * 
 * 主要是把不用的queue item 移到另一个queue中 ,等用时再载入
 * 
 * 把删除的ExpValue对象移入回收站队列,
 * 
 * 删除的ExpValue对象空间会被重复利用,ExpValue对象的绑定数据被丢弃,
 * 
 * 用途是避免了新建ExpValue对象时重新分配空间的耗时
 */
public class RecExpQueue<T> {
	private ConcurrentLinkedQueue<ExpValue<?>> _在用队列 = new ConcurrentLinkedQueue<>();
	private ConcurrentLinkedQueue<ExpValue<?>> _回收队列 = new ConcurrentLinkedQueue<>();

	/**取出在用队列中最早的盒子 但是不移除
	 * 
	 * @return
	 */
	@SuppressWarnings("unchecked")
	ExpValue<T> peek() {
		return (ExpValue<T>) _在用队列.peek();
	}

	/**
	 * 把数据从在用取出 立即放入 回收队列
	 * 
	 * @return
	 */
	ExpValue<T> poll() {
		@SuppressWarnings("unchecked")
		ExpValue<T> te = (ExpValue<T>) _在用队列.poll();
		if (te != null)
			_回收队列.add(te);
		return te;

	}

	boolean isEmpty() {
		return _在用队列.isEmpty();
	}

	/**
	 * 从回收队列 取出盒子 重复使用
	 * 
	 * 如果回收队列没有盒子就 创建一个新的盒子
	 * 
	 * 然后把盒子放到在用队列
	 * 
	 * @param tv
	 */
	@SuppressWarnings("unchecked")
	public void add(T tv) {
		ExpValue<T> te = null;

		if (_回收队列.isEmpty())
			te = new ExpValue<T>(tv);
		else {
			te = (ExpValue<T>) _回收队列.poll();
			te.setValue(tv);
			te.reStamp();

		}
		_在用队列.add(te);
	}

	public String toJson() {
		return JSON.toJSONString(_在用队列);
	}
}
